/**
 * memory.h
 * 
 * Specifies the interface for memory accesses and the definition of the
 * memory map.
 *
 * @author  Philippe Johnson
 */

#ifndef __MEMORY_H__
#define __MEMORY_H__

#include "common.h"
#include "rommanager.h"
#include "snes.h"
#include "mmio.h"

#define MAINMEM_BANKS   0x800              /* Number of banks in main memory */
#define MAINRAM_SIZE    0x8000             /* Size of main memory            */
#define SRAM_SIZE       0x1800             /* Size of extended memory        */

#define GETADDRESS( addr )  (memoryMap[ ( addr & 0xFFF000 ) >> 12 ] + \
                             ((addr) & 0x0FFF))

static void* SRAM[ SRAM_SIZE ];
static void* snesRAM[ MAINRAM_SIZE ];
static void* memoryMap[ MAINMEM_BANKS ];   /* SNES memory map                */

/**
 * initializeMemory
 * Sets up all appropriate memory mappings
 *
 * @param info Information about this particular cartridge
 */
void initializeMemory( CartridgeInfo* info );

/**
 * uninitializeMemory 
 * Frees all associated resources
 */
void uninitializeMemory();

/**
 * memRead8
 * Reads a byte from SNES memory.
 * 
 * @param address The SNES virtual address from which to read.
 * @return The byte-long value at the specified address
 */
u8   memRead8( u32 address );

/**
 * memRead8NoTrap
 * Reads a byte from SNES memory without invoking any MMIO-trapped 
 * functionality. For use in the case where we know there is no trap
 * to be made for a given read.
 * 
 * @param address The SNES virtual address from which to read
 * @return The byte-long value at the specified address
 */
u8   memRead8NoTrap( u32 address );

/**
 * memRead16
 * Reads a word from SNES memory.
 *
 * @param address The SNES virtual address from which to read
 * @return The word-long value at the specified address
 */
u16  memRead16( u32 address );

/**
 * memRead16NoTrap
 * Reads a word from SNES memory without invoking any MMIO-trapped
 * functionality. For use in the case where we know there is no trap
 * to be made for a given read.
 *
 * @param address The SNES virtual address from which to read
 * @return The word-long value at the specified address
 */
u16  memRead16NoTrap( u32 address );

/**
 * memRead24
 * Reads a long from SNES memory.
 *
 * @param address The SNES virtual address from which to read
 * @return the long-long (ha) value at the specified address
 */
u32  memRead24( u32 address );

/**
 * memRead24
 * Reads a word from SNES memory without invoking any MMIO-trapped
 * functionality. For use in the case where we know there is no trap
 * to be made for a given read.
 *
 * @param address The SNES virtual address from which to read
 * @return the long-long (ha) value at the specified address
 */
u32  memRead24NoTrap( u32 address );

/**
 * memWrite8
 * Writes a byte to SNES memory.
 *
 * @param address The address to which to write
 * @param value The byte-long value to write at address
 */
void memWrite8( u32 address, u8 value );

/**
 * memWrite8NoTrap
 * Writes a byte to SNES memory without invoking any MMIO traps.
 *
 * @param address The address to which to write
 * @param value The byte-long value to write at address
 */
void memWrite8NoTrap( u32 address, u8 value );

/**
 * memWrite16
 * Writes a word to SNES memory.
 *
 * @param address The address to which to write
 * @param value The word-long value to write at address
 */
void memWrite16( u32 address, u16 value );

/**
 * memWrite16NoTrap
 * Writes a word to SNES memory without invoking any MMIO traps.
 *
 * @param address The address to which to write
 * @param value The word-long value to write at address
 */
void memWrite16NoTrap( u32 address, u16 value );

#endif /* __MEMORY_H__ */

